const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const xss = require('xss-clean');
const hpp = require('hpp');
const { config } = require('../config/config');

// 基础安全中间件配置
const securityMiddleware = {
  // Helmet 安全头配置
  helmet: helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        scriptSrc: ["'self'"],
        imgSrc: ["'self'", "data:", "https:"],
        connectSrc: ["'self'"],
        fontSrc: ["'self'"],
        objectSrc: ["'none'"],
        mediaSrc: ["'self'"],
        frameSrc: ["'none'"]
      }
    },
    crossOriginEmbedderPolicy: false,
    crossOriginResourcePolicy: { policy: "cross-origin" }
  }),

  // 速率限制配置
  rateLimit: rateLimit({
    windowMs: config.rateLimit.windowMs,
    max: config.rateLimit.maxRequests,
    message: {
      error: '请求过于频繁，请稍后再试',
      retryAfter: Math.ceil(config.rateLimit.windowMs / 1000)
    },
    standardHeaders: true,
    legacyHeaders: false,
    skipSuccessfulRequests: config.rateLimit.skipSuccessfulRequests,
    skipFailedRequests: config.rateLimit.skipFailedRequests,
    keyGenerator: (req) => {
      // 使用用户ID或IP地址作为限制键
      return req.user?.id || req.ip;
    },
    handler: (req, res) => {
      res.status(429).json({
        success: false,
        message: '请求过于频繁，请稍后再试',
        retryAfter: Math.ceil(config.rateLimit.windowMs / 1000)
      });
    }
  }),

  // 严格速率限制（用于敏感操作）
  strictRateLimit: rateLimit({
    windowMs: 15 * 60 * 1000, // 15分钟
    max: 5, // 最多5次请求
    message: {
      error: '操作过于频繁，请稍后再试',
      retryAfter: 900
    },
    standardHeaders: true,
    legacyHeaders: false,
    keyGenerator: (req) => req.user?.id || req.ip
  }),

  // 登录速率限制
  loginRateLimit: rateLimit({
    windowMs: 15 * 60 * 1000, // 15分钟
    max: 5, // 最多5次登录尝试
    message: {
      error: '登录尝试次数过多，请15分钟后再试',
      retryAfter: 900
    },
    standardHeaders: true,
    legacyHeaders: false,
    keyGenerator: (req) => req.ip,
    skipSuccessfulRequests: true
  }),

  // 数据清理中间件
  sanitize: mongoSanitize({
    replaceWith: '_'
  }),

  // XSS 防护
  xss: xss(),

  // HTTP 参数污染防护
  hpp: hpp({
    whitelist: ['filter', 'sort', 'page', 'limit'] // 允许重复的参数
  }),

  // 自定义安全中间件
  customSecurity: (req, res, next) => {
    // 移除敏感头信息
    res.removeHeader('X-Powered-By');
    
    // 添加安全头
    res.setHeader('X-Content-Type-Options', 'nosniff');
    res.setHeader('X-Frame-Options', 'DENY');
    res.setHeader('X-XSS-Protection', '1; mode=block');
    res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
    
    // 检查请求来源
    const allowedOrigins = [config.app.frontendUrl];
    const origin = req.headers.origin;
    
    if (origin && !allowedOrigins.includes(origin)) {
      return res.status(403).json({
        success: false,
        message: '不允许的请求来源'
      });
    }
    
    next();
  },

  // 请求大小限制
  requestSizeLimit: (req, res, next) => {
    const contentLength = parseInt(req.headers['content-length'] || '0');
    const maxSize = 10 * 1024 * 1024; // 10MB
    
    if (contentLength > maxSize) {
      return res.status(413).json({
        success: false,
        message: '请求体过大'
      });
    }
    
    next();
  },

  // 文件类型检查
  fileTypeCheck: (req, res, next) => {
    if (req.files) {
      const files = Array.isArray(req.files) ? req.files : [req.files];
      
      for (const file of files) {
        if (!config.upload.allowedTypes.includes(file.mimetype)) {
          return res.status(400).json({
            success: false,
            message: `不支持的文件类型: ${file.mimetype}`
          });
        }
      }
    }
    
    next();
  },

  // API 版本检查
  apiVersionCheck: (req, res, next) => {
    const apiVersion = req.headers['x-api-version'] || req.query.version;
    const currentVersion = config.app.version;
    
    if (apiVersion && apiVersion !== currentVersion) {
      return res.status(400).json({
        success: false,
        message: `API版本不匹配，当前版本: ${currentVersion}`
      });
    }
    
    next();
  },

  // 请求日志记录
  requestLogger: (req, res, next) => {
    const start = Date.now();
    
    res.on('finish', () => {
      const duration = Date.now() - start;
      const logData = {
        method: req.method,
        url: req.url,
        status: res.statusCode,
        duration: `${duration}ms`,
        ip: req.ip,
        userAgent: req.get('User-Agent'),
        userId: req.user?.id || 'anonymous'
      };
      
      if (res.statusCode >= 400) {
        console.error('Request Error:', logData);
      } else {
        console.log('Request:', logData);
      }
    });
    
    next();
  }
};

module.exports = securityMiddleware; 